/**
 * Project  : Looker
 * Package  : net.freestu.looker.monitor
 * File     : ListMonitor.java
 * Author   : solosky < solosky772@qq.com >
 * Date     : Aug 27, 2009
 * Modified : Aug 27, 2009
 * License  : Apache License 2.0 
 */
package net.freestu.looker.monitor;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

import net.freestu.looker.common.Category;
import net.freestu.looker.common.Looker;
import net.freestu.looker.common.NewsMeta;

import org.apache.log4j.Logger;


/**
 *  新闻列表监视器
 *  仅通过列表来监视新闻的删除和新增
 */
public class ListMonitor extends AbstractMonitor
{
	
	/**
	 * 下载的新闻列表页面
	 */
	private String html;
	
	/**
	 * 日志记录
	 */
	private static Logger logger = Logger.getLogger(ListMonitor.class);
	
	
	/**
	 * 构造函数
     * @param category
     */
    public ListMonitor(Category category)
    {
	    super(category);
    }

	/* (non-Javadoc)
     * @see net.freestu.looker.monitor.AbstractMonitor#start()
     */
    @Override
    public void start()
    {
    	synchronized (category) {    
    	    try {
    	    	logger.info(this+"开始检查...");
    	    	fetchList();
    	    	parseList();
    	 	    checkModify();
    	        finish();
    	    	logger.info(this+"完成检查.");
            } catch (Exception e) {
            	logger.warn(this+"出错 : "+e);
            	e.printStackTrace();
            }
        }
    }
    
    /**
     * 下载前几页的新闻
     * @throws FetcherException 
     * @throws InterruptedException 
     */
    private void fetchList() throws FetcherException, InterruptedException
    {
    	int listPage = this.category.getConfiguration().getInt("listPage");
    	ArrayList<AbstractFetcher> fetcherList = new ArrayList<AbstractFetcher>();
    	FetcherGroup fetcherGroup = new FetcherGroup();
    	AbstractFetcher fetcher = null;
    	for(int i=1; i<=listPage;i++) {
    		fetcher = new HtmlFetcher(category.getPaging().getURL(i));
    		fetcherGroup.addFetcher(fetcher);
    		fetcherList.add(fetcher);
    	}
    	fetcherGroup.start();
    	fetcherGroup.await();
    	//检查是否下载完成
    	boolean allSuccess = true;
    	Iterator <AbstractFetcher> it = fetcherList.iterator();
    	while(it.hasNext()) {
    		fetcher = it.next();
    		if(!fetcher.isSuccess()) {
    			allSuccess = false;
    			break;
    		}else {
				this.html +=(String) fetcher.getFeched();
			}
    	}
    	if(!allSuccess)
    		throw new IllegalStateException(this+"新闻列表没有完全下载完成，退出本次检查");
    }
    
    /**
     * 分析新闻列表页面至新闻信息对象列表
     */
    @SuppressWarnings("unchecked")
    private void parseList()
    {
    	ListParser parser = new ListParser(html, category);
    	parser.parse();
    	category.getListManager()
    	.setCurrentList((ArrayList<NewsMeta>) parser.getParsed());
    	logger.debug(this+"成功解析 ["+category.getListManager().getCurrentList().size()+"] 条新闻");
    }
    
    /**
     * 检查更新
     * @throws IOException 
     */
    private void checkModify() throws IOException
    {
    	NewsMetaListManager listManager = category.getListManager();
    	listManager.readBeforeList();
    	listManager.updateCurrentList(true, true);
    	listManager.checkModify();
    	listManager.saveCurrentList();
    }
	
	/* (non-Javadoc)
     * @see net.freestu.looker.monitor.AbstractMonitor#finish()
     */
    @Override
    public void finish()
    {
    	Looker.listMonitorScheduler.finish(category);
    }
    
    public String toString()
    {
    	return "新闻检查器 - ["+category.getTitle()+"|"+category.getHash()+"] - ";
    }

}
